/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */

#ifndef __SOFT_SPI
#define __SOFT_SPI

#include "zino_pin.h"

typedef struct soft_spi_ios {
    zino_io_t cs;
    zino_io_t clk;
    zino_io_t mosi;
    zino_io_t miso;
}soft_spi_ios_t;
struct soft_spi_bus_ops;
typedef struct soft_spi_bus {
    struct soft_spi_ios *ios;
    uint8_t mode;
    void(*delay_us)(uint8_t us);
    struct soft_spi_bus_ops *ops;//NOTE 先引用后声明的只能用指针
}soft_spi_bus_t;
struct soft_spi_bus_ops {
    uint8_t(*transfer)(soft_spi_bus_t* bus, uint8_t data);
    void(*send_then_send)(soft_spi_bus_t* bus, uint8_t* sbuf1, uint8_t slen1, uint8_t* sbuf2, uint8_t slen2);
    void(*send_then_receive)(soft_spi_bus_t* bus, uint8_t* sbuf, uint8_t slen, uint8_t* rbuf, uint8_t rlen);
};
#define SOFT_SPI_CPHA     (1<<0)                             /* bit[0]:CPHA, clock phase */
#define SOFT_SPI_CPOL     (1<<1)                             /* bit[1]:CPOL, clock polarity */
#define SOFT_SPI_LSB      (0<<2)                             /* bit[2]: 0-LSB */
#define SOFT_SPI_MSB      (1<<2)                             /* bit[2]: 1-MSB */
#define SOFT_SPI_MODE_0       (0 | 0)                        /* CPOL = 0, CPHA = 0 */
#define SOFT_SPI_MODE_1       (0 | SOFT_SPI_CPHA)              /* CPOL = 0, CPHA = 1 */
#define SOFT_SPI_MODE_2       (SOFT_SPI_CPOL | 0)              /* CPOL = 1, CPHA = 0 */
#define SOFT_SPI_MODE_3       (SOFT_SPI_CPOL | SOFT_SPI_CPHA)    /* CPOL = 1, CPHA = 1 */
void soft_spi_bus_init(struct soft_spi_bus* bus, struct soft_spi_ios* ios);
void soft_spi_bus_send_then_send(struct soft_spi_bus* bus, uint8_t* sbuf1, uint8_t slen1, uint8_t* sbuf2, uint8_t slen2);
void soft_spi_bus_send_then_receive(struct soft_spi_bus* bus, uint8_t* sbuf, uint8_t slen, uint8_t* rbuf, uint8_t rlen);
#endif
